package com.ljt.security;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ljt.system.entity.User;
import com.ljt.system.service.UserService;
import com.ljt.system.service.impl.UserDetailsServiceImpl;
import com.ljt.utils.JWTUtil;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * jwt认证拦截器
 */
public class JWTAuthenticationFilter extends BasicAuthenticationFilter {
    @Autowired
    private JWTUtil jwtUtil;

    @Autowired
    private UserService userService;

    @Autowired
    private UserDetailsServiceImpl userDetailsServiceImpl;

    public JWTAuthenticationFilter(AuthenticationManager authenticationManager) {
        super(authenticationManager);
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        // 获取请求头中的jwt
        String jwt = request.getHeader(jwtUtil.getHead());
        // 判断是否为空
        if(StrUtil.isBlankOrUndefined(jwt)){
            chain.doFilter(request,response);
            return;
        }

        // 解析jwt
        Claims claimByToken = jwtUtil.getClaimByToken(jwt);
        if(claimByToken == null){
            throw new JwtException("jwt解析异常");
        }
        if(jwtUtil.isTokenExpired(claimByToken)){
            throw new JwtException("jwt过期");
        }

        // 获取用户名
        String username = claimByToken.getSubject();

        // 根据用户名查询用户信息
        User u = userService.getOne(new QueryWrapper<User>().eq("username", username));

        UsernamePasswordAuthenticationToken token =
                new UsernamePasswordAuthenticationToken(username,null,
                        userDetailsServiceImpl.getGrantedAuthority(u.getId()));
        // 设置认证主体
        SecurityContextHolder.getContext().setAuthentication(token);
        // 放行
        chain.doFilter(request,response);
    }
}
